//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V1.0.0
#include "can_bsp.h"
#include <string.h>

/*CAN 总管理结构体*/
typedef struct
{
	void (*Rx_IT_Callback)(unsigned int id, unsigned char* const buffer, unsigned char length);
	void (*Tx_IT_Callback)(void);
    volatile WHT_CAN_Info_t Info;
}WHT_Data_t;


static WHT_Data_t WHT_CAN1;
static WHT_Data_t WHT_CAN2;
static WHT_Data_t WHT_CAN3;


/*CAN GPIO初始化*/
static void WHT_CAN_BSP_GPIO_Init(WHT_CAN_enum name, const WHT_CAN_Config_t* config)
{
	if (name == CAN_1)
	{
		WHT_GPIO_BSP.WHT_Set_Clock(PortB, ENABLE);
		WHT_GPIO_BSP.WHT_Set_Pin(PortB, Pin8 | Pin9, Hig);
		WHT_GPIO_BSP.WHT_Set_Mode(PortB, Pin8 | Pin9, Mode_AF_PP);
		WHT_GPIO_BSP.WHT_Set_AFIO(PortB, Pin8, AFIO_CAN1);
		WHT_GPIO_BSP.WHT_Set_AFIO(PortB, Pin9, AFIO_CAN1);
	}
	else if (name == CAN_2)
	{
		WHT_GPIO_BSP.WHT_Set_Clock(PortB, ENABLE);
		WHT_GPIO_BSP.WHT_Set_Pin(PortB, Pin5 | Pin6, Hig);
		WHT_GPIO_BSP.WHT_Set_Mode(PortB, Pin5 | Pin6, Mode_AF_PP);
		WHT_GPIO_BSP.WHT_Set_AFIO(PortB, Pin5, AFIO_CAN2);
		WHT_GPIO_BSP.WHT_Set_AFIO(PortB, Pin6, AFIO_CAN2);
	}
}
/*CAN 中断优先级配置*/
static void NVIC_Configuration(WHT_CAN_enum name, const WHT_CAN_Config_t* config)
{
	/* 配置中断源 */
	if (name == CAN_1)
	{
		NVIC_SetPriority(CAN0_RX0_IRQn, config->PreemptionPriority);
		NVIC_EnableIRQ(CAN0_RX0_IRQn);

		NVIC_SetPriority(CAN0_TX_IRQn, config->PreemptionPriority);
		NVIC_EnableIRQ(CAN0_TX_IRQn);
	
		NVIC_SetPriority(CAN0_EWMC_IRQn, config->PreemptionPriority);
		NVIC_EnableIRQ(CAN0_EWMC_IRQn);
	}
#if defined (GD32F450) || defined (GD32F470) || defined (GD32F405) || defined (GD32F425) || defined (GD32F407) || defined (GD32F427)
	else if (name == CAN_2)
	{
		NVIC_SetPriority(CAN1_RX0_IRQn, config->PreemptionPriority);
		NVIC_EnableIRQ(CAN1_RX0_IRQn);

		NVIC_SetPriority(CAN1_TX_IRQn, config->PreemptionPriority);
		NVIC_EnableIRQ(CAN1_TX_IRQn);
	
		NVIC_SetPriority(CAN1_EWMC_IRQn, config->PreemptionPriority);
		NVIC_EnableIRQ(CAN1_EWMC_IRQn);
	}
#endif
}
/*CAN 滤波器配置*/
static void WHT_CAN_BSP_Filter_Config(const WHT_CAN_Config_t* config)
{
	can_filter_parameter_struct CAN_FilterInitStruct;

	CAN_FilterInitStruct.filter_enable       = ENABLE;               //打开过滤器
	CAN_FilterInitStruct.filter_fifo_number  = CAN_FIFO0;            //滤波器给FIFO0
	CAN_FilterInitStruct.filter_bits         = CAN_FILTERBITS_32BIT; //采用32位掩码模式
	CAN_FilterInitStruct.filter_mode         = CAN_FILTERMODE_MASK;  //采用掩码模式

	/* 滤波器0 对于本机通信 */
	CAN_FilterInitStruct.filter_number      = 0; //过滤器组0 这里可设0-13
	//CAN_FilterInitStruct.filter_list_high = (config->ID << 3 | CAN_FF_EXTENDED | CAN_FT_DATA) >> 16;     //扩展ID 数据帧模式
	//CAN_FilterInitStruct.filter_list_low  = (config->ID << 3 | CAN_FF_EXTENDED | CAN_FT_DATA) & 0xFFFF;
	//CAN_FilterInitStruct.filter_mask_high = 0xffff;
	//CAN_FilterInitStruct.filter_mask_low  = 0xffff & (~(0x0f<<3)); //忽略ID的低4bit
    CAN_FilterInitStruct.filter_list_high   = (config->ID << 21 | CAN_FF_STANDARD | CAN_FT_DATA) >> 16;     //标准ID 数据帧模式
    CAN_FilterInitStruct.filter_list_low    = (config->ID << 21 | CAN_FF_STANDARD | CAN_FT_DATA);
	CAN_FilterInitStruct.filter_mask_high   = 0xffff & (~(0x0f<<5)); //忽略ID的低4bit
	CAN_FilterInitStruct.filter_mask_low    = 0xffff;
	can_filter_init(&CAN_FilterInitStruct);

	/* 滤波器1 对于心跳包 */
	CAN_FilterInitStruct.filter_number     = 1; //过滤器组1 这里可设0-13
    CAN_FilterInitStruct.filter_list_high     = ((unsigned int)0x700 << 21 | CAN_FF_STANDARD | CAN_FT_DATA) >> 16; //标准ID 数据帧模式
    CAN_FilterInitStruct.filter_list_low      = ((unsigned int)0x700 << 21 | CAN_FF_STANDARD | CAN_FT_DATA) & 0xFFFF;
	CAN_FilterInitStruct.filter_mask_high = 0xffff;
	CAN_FilterInitStruct.filter_mask_low  = 0xffff;
	can_filter_init(&CAN_FilterInitStruct);
}
/*CAN 配置*/
static ErrStatus WHT_CAN_BSP_Config(WHT_CAN_enum name, const WHT_CAN_Config_t* config)
{
	can_parameter_struct CAN_InitStruct;
	WHT_Data_t* WHT_Data;

	if (name == CAN_1)
	{
		WHT_Data = &WHT_CAN1;
		rcu_periph_clock_enable(RCU_CAN0);
	}
	else if (name == CAN_2)
	{
		WHT_Data = &WHT_CAN2;
		rcu_periph_clock_enable(RCU_CAN1);
	}
	else
	{
		return ERROR;
	}

	WHT_Data->Tx_IT_Callback = config->Tx_IT_Callback;
	WHT_Data->Rx_IT_Callback = config->Rx_IT_Callback;
	memset((void*)&WHT_Data->Info.Error_State, 0, sizeof(WHT_CAN_Error_State_t));
	WHT_Data->Info.TRx_Error_State = CAN_No_Error;
	WHT_Data->Info.TRx_State = CAN_TRx_Idle;

	can_deinit(name);
	WHT_CAN_BSP_GPIO_Init(name, config);
	NVIC_Configuration(name, config);

	can_struct_para_init(CAN_INIT_STRUCT, &CAN_InitStruct);

	CAN_InitStruct.auto_bus_off_recovery = ENABLE;  //自动总线关闭管理功能
	CAN_InitStruct.auto_wake_up       = ENABLE;  //自动总线唤醒功能
	CAN_InitStruct.working_mode       = CAN_NORMAL_MODE;/////CAN_LOOPBACK_MODE;//CAN_NORMAL_MODE;//调试时建议使用回环模式，调试完再改成NORMAL
	CAN_InitStruct.auto_retrans       = ENABLE;  //错误重传
	CAN_InitStruct.rec_fifo_overwrite = DISABLE; //接收FIFO满后覆盖旧报文
	CAN_InitStruct.time_triggered     = DISABLE; //关闭时间触发通信功能
	CAN_InitStruct.trans_fifo_order   = DISABLE; //按ID优先级发送 ENABLE按照先后顺序发送

	//配置速率
	CAN_InitStruct.time_segment_1 = CAN_BT_BS1_6TQ; //时间段1 占用了6个时间单元
	CAN_InitStruct.time_segment_2 = CAN_BT_BS2_3TQ; //时间段2 占用了3个时间单元
	CAN_InitStruct.resync_jump_width = CAN_BT_SJW_2TQ; //重新同步跳跃宽度 2个时间单元
	CAN_InitStruct.prescaler = config->prescaler; //(240mhz / 4) / (6 + 3 + 1) = 6mhz  6mhz / 24 = 250khz

	can_init(name, &CAN_InitStruct);
	WHT_CAN_BSP_Filter_Config(config);

	can_interrupt_enable(name, CAN_INT_RFNE0);//接收邮箱非空中断
	can_interrupt_disable(name, CAN_INT_TME); //发送邮箱空中断

    // 使能所有错误中断
    can_interrupt_enable(name, CAN_INT_WERR | CAN_INT_PERR | CAN_INT_ERRN | CAN_INT_ERR);//ISO 26262 功能安全标准
	 
	return SUCCESS;
}


/*CAN 普通送数据*/
static ErrStatus WHT_CAN_BSP_TxMessage(WHT_CAN_enum name, WHT_CAN_Message_t* tx_message, unsigned int timeout_ms)
{
	can_trasnmit_message_struct TxMessage;
	WHT_Data_t* WHT_Data;
	unsigned char TransmitMailbox;
	TickType_t xTicksToDelay;
	
	if (name == CAN_1)
	{
		WHT_Data = &WHT_CAN1;
	}
	else if (name == CAN_2)
	{
		WHT_Data = &WHT_CAN2;
	}
	else
	{
		return ERROR;
	}
	
	WHT_Data->Info.TRx_State = CAN_TRx_Busy;
	WHT_Data->Info.TRx_Error_State = CAN_No_Error;

	TxMessage.tx_sfid = tx_message->ID;
	TxMessage.tx_efid = tx_message->ID;
	TxMessage.tx_ft = CAN_FT_DATA;
	TxMessage.tx_ff = CAN_FF_STANDARD; //CAN_FF_STANDARD 标准帧 CAN_FF_EXTENDED 扩展帧
	TxMessage.tx_dlen = tx_message->length;
	memcpy(TxMessage.tx_data, tx_message->buffer, tx_message->length);

	can_interrupt_disable(name, CAN_INT_TME); //发送邮箱空中断

	// 获取发送邮箱
	xTicksToDelay = pdMS_TO_TICKS(timeout_ms);
	while (1)
	{
		TransmitMailbox = can_message_transmit(name, &TxMessage);
		if (TransmitMailbox == CAN_NOMAILBOX)
		{
			if (xTicksToDelay > 0)
			{
				xTicksToDelay--;
				vTaskDelay(1);
			}
			else
			{
				WHT_Data->Info.TRx_State = CAN_TRx_Idle;
				return ERROR;
			}
		}
		else
		{
			break;
		}
	}

	WHT_Data->Info.TRx_State = CAN_TRx_Idle;
	return SUCCESS;// 发送成功
}
/*CAN 中断发送数据*/
static ErrStatus WHT_CAN_BSP_TxMessage_IT(WHT_CAN_enum name, WHT_CAN_Message_t* tx_message)
{
	can_trasnmit_message_struct TxMessage;
	WHT_Data_t* WHT_Data;


	if (tx_message->length > sizeof(TxMessage.tx_data))
	{
		return ERROR;
	}
	
	if (name == CAN_1)
	{
		WHT_Data = &WHT_CAN1;
	}
	else if (name == CAN_2)
	{
		WHT_Data = &WHT_CAN2;
	}
	else
	{
		return ERROR;
	}
	
	WHT_Data->Info.TRx_State = CAN_TRx_Busy;

	TxMessage.tx_sfid = tx_message->ID;
	TxMessage.tx_efid = tx_message->ID;
	TxMessage.tx_ft = CAN_FT_DATA;
	TxMessage.tx_ff = CAN_FF_STANDARD; //CAN_FF_STANDARD 标准帧 CAN_FF_EXTENDED 扩展帧
	TxMessage.tx_dlen = tx_message->length;
	memcpy(TxMessage.tx_data, tx_message->buffer, tx_message->length);

	can_interrupt_enable(name, CAN_INT_TME); //发送邮箱空中断
    // 发送CAN消息 (触发第一次发送)
	if (can_message_transmit(name, &TxMessage) == CAN_NOMAILBOX)
	{
		WHT_Data->Info.TRx_Error_State = CAN_Tx_Error;
		WHT_Data->Info.TRx_State = CAN_TRx_Idle;
		return ERROR; // 发送失败
    }
	else
	{
		return SUCCESS; // 发送成功
	}
}



/*全局常量*/
const WHT_CAN_BSP_t WHT_CAN_BSP =
{
	.WHT_CAN1_Info    = (WHT_CAN_Info_t*)&WHT_CAN1.Info,
	.WHT_CAN2_Info    = (WHT_CAN_Info_t*)&WHT_CAN2.Info,
	.WHT_CAN3_Info    = (WHT_CAN_Info_t*)&WHT_CAN3.Info,
	.WHT_Config       = WHT_CAN_BSP_Config,
	.WHT_TxMessage    = WHT_CAN_BSP_TxMessage,
	.WHT_TxMessage_IT = WHT_CAN_BSP_TxMessage_IT,
};




/* 发送中断服务程序回调函数 */
static void WHT_CAN_BSP_IRQHandler_Send(WHT_CAN_enum name, WHT_Data_t* WHT_Data)
{
    // 识别哪个邮箱发送完成
    if(can_interrupt_flag_get(name, CAN_INT_FLAG_MTF0) != RESET)
	{
        can_interrupt_flag_clear(name, CAN_INT_FLAG_MTF0); // 清除邮箱0请求完成标志
        // 处理邮箱0发送完成的操作
    }
        
    if(can_interrupt_flag_get(name, CAN_INT_FLAG_MTF1) != RESET)
	{
        can_interrupt_flag_clear(name, CAN_INT_FLAG_MTF1); // 清除邮箱1请求完成标志
        // 处理邮箱1发送完成的操作
    }
        
    if(can_interrupt_flag_get(name, CAN_INT_FLAG_MTF2) != RESET)
	{
        can_interrupt_flag_clear(name, CAN_INT_FLAG_MTF2); // 清除邮箱2请求完成标志
        // 处理邮箱2发送完成的操作
    }

	WHT_Data->Info.TRx_State = CAN_TRx_Idle;
	if (WHT_Data->Tx_IT_Callback)
	{
		WHT_Data->Tx_IT_Callback();
	}
}
/* 接收中断服务程序回调函数 */
static void WHT_CAN_BSP_IRQHandler_Receive(WHT_CAN_enum name, WHT_Data_t* WHT_Data)
{
	can_receive_message_struct RxMessage;

	if (can_interrupt_flag_get(name, CAN_INT_FLAG_RFL0) != RESET)
	{
		can_message_receive(name, CAN_FIFO0, &RxMessage);
		if (WHT_Data->Rx_IT_Callback)
		{
			WHT_Data->Rx_IT_Callback(RxMessage.rx_ff == CAN_FF_STANDARD ? RxMessage.rx_sfid : RxMessage.rx_efid, RxMessage.rx_data, RxMessage.rx_dlen);
		}
	}
}
/* 错误中断服务函数回调函数 */
static void WHT_CAN_BSP_IRQHandler_Error(WHT_CAN_enum name, WHT_Data_t* WHT_Data)
{
    // 按优先级顺序处理错误（BOF > EPV > EWG > LEC）
    if (can_interrupt_flag_get(name, CAN_INT_FLAG_BOERR) != RESET)
	{
		/* 总线关闭错误处理（最高优先级） */
		// CAN控制器关闭
		can_deinit(name);

		// 更新错误状态
		WHT_Data->Info.Error_State.error_count++;
		WHT_Data->Info.Error_State.error_bof_count++;
		WHT_Data->Info.Error_State.is_bus_off = ENABLE;

        can_interrupt_flag_clear(name, CAN_INT_FLAG_ERRIF);
    }
    else if (can_interrupt_flag_get(name, CAN_INT_FLAG_PERR) != RESET)
	{
		/* 错误被动状态处理 */
		// 更新错误状态
		WHT_Data->Info.Error_State.error_count++;
		WHT_Data->Info.Error_State.error_epv_count++;
		WHT_Data->Info.Error_State.is_error_passive = ENABLE;

		// 执行降级策略（如降低发送频率、增加重传次数）应用层处理

        can_interrupt_flag_clear(name, CAN_INT_FLAG_ERRIF);
    }
    else if (can_interrupt_flag_get(name, CAN_INT_FLAG_WERR) != RESET)
	{
		/* 错误警告处理 */
		// 更新错误状态
		WHT_Data->Info.Error_State.error_count++;
		WHT_Data->Info.Error_State.error_ewg_count++;

		// 接近错误被动状态，应用层去处理

        can_interrupt_flag_clear(name, CAN_INT_FLAG_ERRIF);
    }
    else if (can_interrupt_flag_get(name, CAN_INT_FLAG_ERRN) != RESET)
	{
		/* 最新错误码处理 */
		// 获取并记录具体错误码
		WHT_Data->Info.Error_State.last_error_code = can_error_get(name);
		/*
		CAN_ERROR_NONE          // 无错误（可能是错误已清除）
		CAN_ERROR_FILL          // 位填充错误
		CAN_ERROR_FORMATE       // 格式错误
		CAN_ERROR_ACK           // ACK错误（无应答）
		CAN_ERROR_BITRECESSIVE  // 位错误（发送1收到0）
		CAN_ERROR_BITDOMINANTER // 位错误（发送0收到1）
		CAN_ERROR_CRC           // CRC错误
		CAN_ERROR_SOFTWARECFG   // 软件设置错误
		*/
		if (WHT_Data->Info.Error_State.last_error_code == CAN_ERROR_ACK)
		{
			printf("CAN No ACK\r\n");
		}
        can_interrupt_flag_clear(name, CAN_INT_FLAG_ERRIF);
    }
}

/* CAN1 发送中断服务程序 */
void CAN0_TX_IRQHandler(void)
{
	WHT_CAN_BSP_IRQHandler_Send(CAN_1, &WHT_CAN1);
}
/* CAN2 发送中断服务程序 */
void CAN1_TX_IRQHandler(void)
{
	WHT_CAN_BSP_IRQHandler_Send(CAN_2, &WHT_CAN2);
}


/* CAN1 接收中断服务程序 */
void CAN0_RX0_IRQHandler(void)
{
	WHT_CAN_BSP_IRQHandler_Receive(CAN_1, &WHT_CAN1);
}
/* CAN2 接收中断服务程序 */
void CAN1_RX0_IRQHandler(void)
{
	WHT_CAN_BSP_IRQHandler_Receive(CAN_2, &WHT_CAN2);
}


/* CAN1错误中断服务函数 */
void CAN0_EWMC_IRQHandler(void)
{
	WHT_CAN_BSP_IRQHandler_Error(CAN_1, &WHT_CAN1);
}
/* CAN2错误中断服务函数 */
void CAN1_EWMC_IRQHandler(void)
{
	WHT_CAN_BSP_IRQHandler_Error(CAN_2, &WHT_CAN2);
}

